home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD 2.1 / Amiga Developer CD v2.1.iso / CDTV / cdtvtools-20 / cdtv_device / cdtv.device.examples < prev   
Encoding:
Text File  |  1992-02-06  |  19.1 KB  |  971 lines

  1. /*
  2. Directory
  3. ---------
  4.  
  5. Assumptions
  6.  
  7. CDTV_RESET
  8. CDTV_READ
  9. CDTV_MOTOR
  10. CDTV_SEEK
  11. CDTV_CHANGENUM
  12. CDTV_CHANGESTATE
  13. CDTV_ADDCHANGEINT
  14. CDTV_REMCHANGEINT
  15. CDTV_QUICKSTATUS
  16. CDTV_INFO
  17. CDTV_ISROM
  18. CDTV_FRONTPANEL
  19. CDTV_FRAMECALL
  20. CDTV_FRAMECOUNT
  21. CDTV_READXL
  22. CDTV_PLAYTRACK
  23. CDTV_PLAYLSN
  24. CDTV_PLAYMSF
  25. CDTV_PLAYSEGSLSN
  26. CDTV_PLAYSEGSMSF
  27. CDTV_TOCLSN
  28. CDTV_TOCMSF
  29. CDTV_SUBQLSN
  30. CDTV_SUBQMSF
  31. CDTV_PAUSE
  32. CDTV_STOPPLAY
  33. CDTV_POKESEGLSN
  34. CDTV_POKESEGMSF
  35. CDTV_MUTE
  36. CDTV_FADE
  37. CDTV_POKEPLAYLSN
  38. CDTV_POKEPLAYMSF
  39. CDTV_GENLOCK
  40. */
  41.  
  42.  
  43. /*************************
  44.  Assumptions
  45.  *************************/
  46.  
  47.     {
  48.     struct MsgPort *IOPort;
  49.     struct IOStdReq *IOReq;
  50.     BYTE Err;
  51.  
  52.     // Init: Create request
  53.     IOPort = CreatePort( 0, 0 );
  54.     if ( ! IOPort )
  55.         Error( NO_PORT );
  56.  
  57.     IOReq = CreateStdIO( IOPort );
  58.     if ( ! IOReq )
  59.         Error( NO_REQUEST );
  60.  
  61.     if ( OpenDevice( CDTV_NAME, 0, IOReq, 0 ) )
  62.         {
  63.         IOReq->io_Device = NULL;
  64.         Error( OPEN_DEV );
  65.         }
  66.  
  67.     // Example code here...
  68.  
  69.     // Quit: Remove request (Error() must call this)
  70.     if ( IOReq )
  71.         {
  72.         if ( IOReq->io_Device )
  73.             CloseDevice( (struct IORequest *) IOReq );
  74.  
  75.         DeleteStdIO( IOReq );
  76.         }
  77.  
  78.     if ( IOPort )
  79.         DeletePort( IOPort );
  80.     }
  81.  
  82.  
  83. /*************************
  84.  CDTV_RESET
  85.  *************************/
  86.  
  87.     {
  88.     IOReq->io_Command = CDTV_RESET;
  89.     IOReq->io_Offset  = 0;
  90.     IOReq->io_Length  = 0;
  91.     IOReq->io_Data    = NULL;
  92.     if ( Err = DoIO( (struct IORequest *) IOReq ) )
  93.         printf( "IO Error %ld\n", Err );
  94.     }
  95.  
  96.  
  97. /*************************
  98.  CDTV_READ
  99.  *************************/
  100.  
  101.  
  102.     {
  103.     static UBYTE Buffer[ 2048 + READ_PAD_BYTES ];
  104.     ULONG Sector;
  105.     ULONG Position;
  106.     ULONG Length;
  107.  
  108.     // - Remember to add READ_PAD_BYTES to read's (and allow
  109.     //   for the extra room in the Buffer).
  110.     Sector          = 112;
  111.     Position      = ( Sector * 2048 );
  112.     Length          = 2048;
  113.  
  114.     IOReq->io_Command = CDTV_READ;
  115.     IOReq->io_Offset  = Position;
  116.     IOReq->io_Length  = ( Length + READ_PAD_BYTES );
  117.     IOReq->io_Data    = Buffer;
  118.     if ( Err = DoIO( (struct IORequest *) IOReq ) )
  119.         printf( "IO Error %ld\n", Err );
  120.     }
  121.  
  122.  
  123. /*************************
  124.  CDTV_MOTOR
  125.  *************************/
  126.  
  127.     {
  128.     ULONG PreviousState;
  129.  
  130.     IOReq->io_Command = CDTV_MOTOR;
  131.     IOReq->io_Offset  = 0;
  132.     IOReq->io_Length  = FALSE;    // Turn motor off
  133.     IOReq->io_Data    = NULL;
  134.     if ( Err = DoIO( (struct IORequest *) IOReq ) )
  135.         printf( "IO Error %ld\n", Err );
  136.  
  137.     PreviousState      = IOReq->io_Actual;
  138.     }
  139.  
  140.  
  141. /*************************
  142.  CDTV_SEEK
  143.  *************************/
  144.  
  145.     {
  146.     ULONG Position      = ( 16 * 2048 );
  147.  
  148.     IOReq->io_Command = CDTV_SEEK;
  149.     IOReq->io_Offset  = Position;
  150.     IOReq->io_Length  = 0;
  151.     IOReq->io_Data    = NULL;
  152.     if ( Err = DoIO( (struct IORequest *) IOReq ) )
  153.         printf( "IO Error %ld\n", Err );
  154.     }
  155.  
  156.  
  157. /*************************
  158.  CDTV_CHANGENUM
  159.  *************************/
  160.  
  161.     {
  162.     IOReq->io_Command = CDTV_CHANGENUM;
  163.     IOReq->io_Offset  = 0;
  164.     IOReq->io_Length  = 0;
  165.     IOReq->io_Data    = NULL;
  166.     if ( Err = DoIO( (struct IORequest *) IOReq ) )
  167.         printf( "IO Error %ld\n", Err );
  168.  
  169.     printf( "%ld disk changes\n", IOReq->io_Actual );
  170.     }
  171.  
  172.  
  173. /*************************
  174.  CDTV_CHANGESTATE
  175.  *************************/
  176.  
  177.     {
  178.     IOReq->io_Command = CDTV_CHANGESTATE;
  179.     IOReq->io_Offset  = 0;
  180.     IOReq->io_Length  = 0;
  181.     IOReq->io_Data    = NULL;
  182.     if ( Err = DoIO( (struct IORequest *) IOReq ) )
  183.         printf( "IO Error %ld\n", Err );
  184.  
  185.     if ( IOReq->io_Actual )
  186.         printf( "CD is not in drive\n" );
  187.     else
  188.         printf( "CD is in drive\n" );
  189.     }
  190.  
  191.  
  192. /*************************
  193.  CDTV_ADDCHANGEINT
  194.  *************************/
  195.  
  196. struct Interrupt ChangeInt;
  197.  
  198. void __interrupt __saveds InterruptCode(
  199.     void
  200.     )
  201.     {
  202.     // Do something
  203.     }
  204.  
  205.     {
  206.     ChangeInt.is_Node.ln_Type = NT_INTERRUPT;
  207.     ChangeInt.is_Code      = InterruptCode;
  208.  
  209.     IOReq->io_Command = CDTV_ADDCHANGEINT;
  210.     IOReq->io_Offset  = 0;
  211.     IOReq->io_Length  = 0;
  212.     IOReq->io_Data    = (APTR) &ChangeInt;
  213.     SendIO( (struct IORequest *) IOReq );
  214.  
  215.     // Refer to CDTV_REMCHANGEINT for removal
  216.     }
  217.  
  218.  
  219. /*************************
  220.  CDTV_REMCHANGEINT
  221.  *************************/
  222.  
  223. struct Interrupt ChangeInt;
  224.  
  225. void __interrupt __saveds InterruptCode(
  226.     void
  227.     )
  228.     {
  229.     // Do something
  230.     }
  231.  
  232.     {
  233.     // Refer to CDTV_ADDCHANGEINT for adding
  234.     // ChangeInt
  235.  
  236.     // (do not need WaitIO()).
  237.     IOReq->io_Command = CDTV_REMCHANGEINT;
  238.     IOReq->io_Offset  = 0;
  239.     IOReq->io_Length  = 0;
  240.     IOReq->io_Data    = (APTR) &ChangeInt;
  241.     DoIO( (struct IORequest *) IOReq );
  242.     }
  243.  
  244.  
  245. /*************************
  246.  CDTV_QUICKSTATUS
  247.  *************************/
  248.  
  249.     {
  250.     IOReq->io_Command = CDTV_QUICKSTATUS;
  251.     IOReq->io_Offset  = 0;
  252.     IOReq->io_Length  = 0;
  253.     IOReq->io_Data    = NULL;
  254.     if ( Err = DoIO( (struct IORequest *) IOReq ) )
  255.         printf( "IO Error %ld\n", Err );
  256.  
  257.     // Valid flags:
  258.     if ( IOReq->io_Actual & QSF_AUDIO )
  259.         printf( "Audio playing\n" );
  260.  
  261.     if ( IOReq->io_Actual & QSF_SPIN )
  262.         printf( "CD is spinning\n" );
  263.  
  264.     if ( IOReq->io_Actual & QSF_DISK )
  265.         printf( "CD in drive\n" );
  266.     }
  267.  
  268.  
  269. /*************************
  270.  CDTV_INFO
  271.  *************************/
  272.  
  273.     {
  274.     IOReq->io_Command = CDTV_INFO;
  275.     IOReq->io_Offset  = CDTV_INFO_FRAME_RATE;
  276.     IOReq->io_Length  = 0;
  277.     IOReq->io_Data    = NULL;
  278.     if ( Err = DoIO( (struct IORequest *) IOReq ) )
  279.         printf( "IO Error %ld\n", Err );
  280.  
  281.     printf( "Frame rate: %ld frames/second\n", IOReq->Actual );
  282.     }
  283.  
  284.  
  285. /*************************
  286.  CDTV_ISROM
  287.  *************************/
  288.  
  289.     {
  290.     IOReq->io_Command = CDTV_ISROM;
  291.     IOReq->io_Offset  = 0;
  292.     IOReq->io_Length  = 0;
  293.     IOReq->io_Data    = NULL;
  294.     if ( Err = DoIO( (struct IORequest *) IOReq ) )
  295.         printf( "IO Error %ld\n", Err );
  296.  
  297.     if ( IOReq->io_Actual )
  298.         printf( "CD is a CD-ROM\n" );
  299.     else
  300.         printf( "CD is an audio CD\n" );
  301.     }
  302.  
  303.  
  304. /*************************
  305.  CDTV_FRONTPANEL
  306.  *************************/
  307.  
  308.     {
  309.     IOReq->io_Command = CDTV_FRONTPANEL;
  310.     IOReq->io_Offset  = 0;
  311.     IOReq->io_Length  = FALSE;    // to disable front panel
  312.     IOReq->io_Data    = NULL;
  313.     if ( Err = DoIO( (struct IORequest *) IOReq ) )
  314.         printf( "IO Error %ld\n", Err );
  315.     }
  316.  
  317.  
  318. /*************************
  319.  CDTV_FRAMECALL
  320.  *************************/
  321.  
  322. void __interrupt __saveds __asm InterruptCode(
  323.     register __a2 struct IOStdReq *Request
  324.     )
  325.     {
  326.     // Do something
  327.     return( 0 );
  328.     }
  329.  
  330.     {
  331.     ULONG Frames = ( 2 * 75 );    // every 2 seconds
  332.  
  333.     IOReq->io_Command = CDTV_FRAMECALL;
  334.     IOReq->io_Offset  = 0;
  335.     IOReq->io_Length  = Frames;
  336.     IOReq->io_Data    = (APTR) InterruptCode;
  337.     SendIO( (struct IORequest *) IOReq );
  338.  
  339.     /*
  340.      *
  341.      * Body of code goes here
  342.      *
  343.      */
  344.  
  345.     // Cleanup:
  346.     // Proper way to terminate
  347.     AbortIO( (struct IORequest *) IOReq );
  348.     WaitIO( (struct IORequest *) IOReq );
  349.     }
  350.  
  351.  
  352. /*************************
  353.  CDTV_FRAMECOUNT
  354.  *************************/
  355.  
  356.     {
  357.     IOReq->io_Command = CDTV_FRAMECOUNT;
  358.     IOReq->io_Offset  = 0;
  359.     IOReq->io_Length  = 0;
  360.     IOReq->io_Data    = NULL;
  361.     if ( Err = DoIO( (struct IORequest *) IOReq ) )
  362.         printf( "IO Error %ld\n", Err );
  363.  
  364.     printf( "%ld frames since start\n", IOReq->io_Actual );
  365.     }
  366.  
  367.  
  368. /*************************
  369.  CDTV_READXL
  370.  *************************/
  371.  
  372. void __interrupt __saveds __asm InterruptCode(
  373.     register __a2 CDXL *NodeCompleted
  374.     )
  375.     {
  376.     // Do something
  377.     return( 0 );
  378.     }
  379.  
  380.     {
  381.     static UBYTE Buffer[ 4 ][ 2048 ];
  382.     struct MinList    CDXLList;
  383.     struct CDXL    CDXLNode[ 4 ];
  384.     ULONG Sector     = 16;
  385.     ULONG NumSectors = 4;
  386.     ULONG i;
  387.  
  388.     // Prepare list
  389.     NewList( (struct List *) &CDXLList );
  390.  
  391.     for ( i = 0; i < 4; i++ )
  392.         {
  393.         AddTail( (struct List *) &CDXLList, (struct Node *) &CDXLNode[ i ] );
  394.         CDXLNode[ i ].Buffer   = Buffer[ i ];
  395.         CDXLNode[ i ].Length   = 2048;
  396.         CDXLNode[ i ].DoneFunc = InterruptCode;
  397.         }
  398.  
  399.     // Start CDXL
  400.     IOReq->io_Command = CDTV_READXL;
  401.     IOReq->io_Offset  = Sector;
  402.     IOReq->io_Length  = NumSectors;
  403.     IOReq->io_Data    = (APTR) CDXLList.mlh_Head;
  404.     SendIO( (struct IORequest *) IOReq );
  405.  
  406.     /*
  407.      *
  408.      * Body of code goes here
  409.      *
  410.      */
  411.  
  412.     // Cleanup:
  413.     // Proper way to terminate
  414.     AbortIO( (struct IORequest *) IOReq );
  415.     WaitIO( (struct IORequest *) IOReq );
  416.  
  417.     // Then a SEEK is required to force the drive to stop (sometimes necessary)
  418.     IOReq->io_Command = CDTV_SEEK;
  419.     IOReq->io_Offset  = 0;        // or next position
  420.     IOReq->io_Length  = 0;
  421.     IOReq->io_Data    = NULL;
  422.  
  423.     if ( Err = DoIO( (struct IORequest *) IOReq ) )
  424.         printf( "IO Error %ld\n", Err );
  425.     }
  426.  
  427.  
  428. /*************************
  429.  CDTV_PLAYTRACK
  430.  *************************/
  431.  
  432.     {
  433.     ULONG StartTrack = 4;
  434.     ULONG StopTrack     = 6;
  435.  
  436.     IOReq->io_Command = CDTV_PLAYTRACK;
  437.     IOReq->io_Offset  = StartTrack;
  438.     IOReq->io_Length  = StopTrack;
  439.     IOReq->io_Data    = NULL;
  440.     if ( Err = DoIO( (struct IORequest *) IOReq ) )
  441.         printf( "IO Error %ld\n", Err );
  442.     }
  443.  
  444.  
  445. /*************************
  446.  CDTV_PLAYLSN
  447.  *************************/
  448.  
  449.     {
  450.     CDPOS StartSector;
  451.     CDPOS SectorsLength;
  452.  
  453.     StartSector.LSN   = 16;
  454.     SectorsLength.LSN = 300;
  455.  
  456.     IOReq->io_Command = CDTV_PLAYLSN;
  457.     IOReq->io_Offset  = StartSector;
  458.     IOReq->io_Length  = SectorsLength;
  459.     IOReq->io_Data    = NULL;
  460.     if ( Err = DoIO( (struct IORequest *) IOReq ) )
  461.         printf( "IO Error %ld\n", Err );
  462.     }
  463.  
  464.  
  465. /*************************
  466.  CDTV_PLAYMSF
  467.  *************************/
  468.  
  469.     {
  470.     CDPOS StartMSF;
  471.     CDPOS StopMSF;
  472.  
  473.     StartMSF.Raw      = TOMSF( 5,  0,  0 );
  474.     StopMSF.Raw      = TOMSF( 5, 10, 25 );
  475.  
  476.     IOReq->io_Command = CDTV_PLAYMSF;
  477.     IOReq->io_Offset  = (ULONG) StartMSF;
  478.     IOReq->io_Length  = (ULONG) StopMSF;
  479.     IOReq->io_Data    = NULL;
  480.     if ( Err = DoIO( (struct IORequest *) IOReq ) )
  481.         printf( "IO Error %ld\n", Err );
  482.     }
  483.  
  484.  
  485. /*************************
  486.  CDTV_PLAYSEGSLSN
  487.  *************************/
  488.  
  489. void __interrupt __saveds __asm InterruptCode(
  490.     register __a2 CDAudioSeg *CompletedSeg
  491.     )
  492.     {
  493.     // Do something
  494.     return( 0 );
  495.     }
  496.  
  497.     {
  498.     struct MinList    SegList;
  499.     struct CDAudioSeg SegNode;
  500.  
  501.     // Prepare list
  502.     NewList( (struct List *) &SegList );
  503.  
  504.     AddTail( (struct List *) &SegList, (struct Node *) &SegNode );
  505.     SegNode.Start.LSN = 16;
  506.     SegNode.Stop.LSN  = 300;
  507.     SegNode.StartFunc = InterruptCode;
  508.  
  509.     IOReq->io_Command = CDTV_PLAYSEGSLSN;
  510.     IOReq->io_Offset  = 0;
  511.     IOReq->io_Length  = 0;
  512.     IOReq->io_Data    = (APTR) SegList.mlh_Head;
  513.     SendIO( (struct IORequest *) IOReq );
  514.  
  515.     /*
  516.      *
  517.      * Body of code goes here
  518.      *
  519.      */
  520.  
  521.     // Cleanup:
  522.     WaitIO( (struct IORequest *) IOReq );
  523.     }
  524.  
  525.  
  526. /*************************
  527.  CDTV_PLAYSEGSMSF
  528.  *************************/
  529.  
  530. void __interrupt __saveds __asm InterruptCode(
  531.     register __a2 CDAudioSeg *CompletedSeg
  532.     )
  533.     {
  534.     // Do something
  535.     return( 0 );
  536.     }
  537.  
  538.     {
  539.     struct MinList    SegList;
  540.     struct CDAudioSeg SegNode;
  541.  
  542.     // Prepare list
  543.     NewList( (struct List *) &SegList );
  544.  
  545.     AddTail( (struct List *) &SegList, (struct Node *) &SegNode );
  546.     SegNode.Start.Raw = TOMSF( 5,  0,  0 );
  547.     SegNode.Stop.Raw  = TOMSF( 5, 10, 25 );
  548.     SegNode.StartFunc = InterruptCode;
  549.  
  550.     IOReq->io_Command = CDTV_PLAYSEGSMSF;
  551.     IOReq->io_Offset  = 0;
  552.     IOReq->io_Length  = 0;
  553.     IOReq->io_Data    = (APTR) SegList.mlh_Head;
  554.     SendIO( (struct IORequest *) IOReq );
  555.  
  556.     /*
  557.      *
  558.      * Body of code goes here
  559.      *
  560.      */
  561.  
  562.     // Cleanup:
  563.     WaitIO( (struct IORequest *) IOReq );
  564.     }
  565.  
  566.  
  567. /*************************
  568.  CDTV_TOCLSN
  569.  *************************/
  570.  
  571.     {
  572.     static struct CDTOC TOCArray[ 100 ];
  573.     LONG i;
  574.  
  575.     IOReq->io_Command = CDTV_TOCLSN;
  576.     IOReq->io_Offset  = 0;            // 0=Summary, or #
  577.     IOReq->io_Length  = 100;
  578.     IOReq->io_Data    = (APTR) TOCArray;
  579.     if ( Err = DoIO( (struct IORequest *) IOReq ) )
  580.         printf( "IO Error %ld\n", Err );
  581.  
  582.     // Disk summary
  583.     printf( "Tracks %d to %d\n",
  584.         TOCArray[ 0 ].Track,
  585.         TOCArray[ 0 ].LastTrack );
  586.  
  587.     // TOC
  588.     for ( i = 1; i <= CDTVIOReq->io_Actual; i++ )
  589.         printf( "Track %d starts at sector %d\n",
  590.             i,
  591.             TOCArray[ 1 ].Position.LSN );
  592.     }
  593.  
  594.  
  595. /*************************
  596.  CDTV_TOCMSF
  597.  *************************/
  598.  
  599.     {
  600.     static struct CDTOC TOCArray[ 100 ];
  601.     LONG i;
  602.  
  603.     IOReq->io_Command = CDTV_TOCMSF;
  604.     IOReq->io_Offset  = 0;            // 0=Summary, or #
  605.     IOReq->io_Length  = 100;
  606.     IOReq->io_Data    = (APTR) TOCArray;
  607.     if ( Err = DoIO( (struct IORequest *) IOReq ) )
  608.         printf( "IO Error %ld\n", Err );
  609.  
  610.     // Disk summary
  611.     printf( "Tracks %d to %d\n",
  612.         TOCArray[ 0 ].Track,
  613.         TOCArray[ 0 ].LastTrack );
  614.  
  615.     // TOC
  616.     for ( i = 1; i <= CDTVIOReq->io_Actual; i++ )
  617.         printf( "Track %d starts at Minute:Second:Frame %d:%d:%d\n",
  618.             i,
  619.             TOCArray[ 1 ].Position.MSF.Minute,
  620.             TOCArray[ 1 ].Position.MSF.Second,
  621.             TOCArray[ 1 ].Position.MSF.Frame );
  622.     }
  623.  
  624.  
  625. /*************************
  626.  CDTV_SUBQLSN
  627.  *************************/
  628.  
  629.     {
  630.     struct CDSubQ ReqSubQ;
  631.     UBYTE AddrInfo;
  632.  
  633.     IOReq->io_Command = CDTV_SUBQLSN;
  634.     IOReq->io_Offset  = 0;
  635.     IOReq->io_Length  = 0;
  636.     IOReq->io_Data    = (APTR) ReqSubQ;
  637.     if ( Err = DoIO( (struct IORequest *) IOReq ) )
  638.         printf( "IO Error %ld\n", Err );
  639.  
  640.     // First check that it is valid
  641.     AddrInfo = ( ReqSubQ.AddrCtrl & ADRCTL_MASK );
  642.     if ( AddrInfo == ADRCTL_NOMODE )
  643.         return;        // INVALID SUBQ
  644.  
  645.     switch ( ReqSubQ.Status )
  646.         {
  647.         case ( SQSTAT_NOTVALID ):
  648.         case ( SQSTAT_NOSTAT   ):
  649.             return;        // INVALID SUBQ
  650.  
  651.         case ( SQSTAT_PLAYING  ):
  652.             printf( "CD Playing\n" );
  653.             break;
  654.  
  655.         case ( SQSTAT_PAUSED   ):
  656.             printf( "CD Paused\n" );
  657.             break;
  658.  
  659.         case ( SQSTAT_DONE     ):
  660.             printf( "Last Play finished normally\n" );
  661.             break;
  662.  
  663.         case ( SQSTAT_ERROR    ):
  664.             printf( "Last Play finished with error\n" );
  665.             break;
  666.         }
  667.  
  668.     // Position
  669.     if ( AddrInfo == ADRCTL_POSITION )
  670.         {
  671.         printf( "Current track %d, index %d\n",
  672.             ReqSubQ.Track,
  673.             ReqSubQ.Index );
  674.  
  675.         printf( "Sector %d into CD, sector %d into track\n",
  676.             ReqSubQ.DiskPosition.LSN,
  677.             ReqSubQ.TrackPosition.LSN );
  678.         }
  679.     }
  680.  
  681.  
  682. /*************************
  683.  CDTV_SUBQMSF
  684.  *************************/
  685.  
  686.     {
  687.     struct CDSubQ ReqSubQ;
  688.     UBYTE AddrInfo;
  689.  
  690.     IOReq->io_Command = CDTV_SUBQMSF;
  691.     IOReq->io_Offset  = 0;
  692.     IOReq->io_Length  = 0;
  693.     IOReq->io_Data    = (APTR) ReqSubQ;
  694.     if ( Err = DoIO( (struct IORequest *) IOReq ) )
  695.         printf( "IO Error %ld\n", Err );
  696.  
  697.     // First check that it is valid
  698.     AddrInfo = ( ReqSubQ.AddrCtrl & ADRCTL_MASK );
  699.     if ( AddrInfo == ADRCTL_NOMODE )
  700.         return;        // INVALID SUBQ
  701.  
  702.     switch ( ReqSubQ.Status )
  703.         {
  704.         case ( SQSTAT_NOTVALID ):
  705.         case ( SQSTAT_NOSTAT   ):
  706.             return;        // INVALID SUBQ
  707.  
  708.         case ( SQSTAT_PLAYING  ):
  709.             printf( "CD Playing\n" );
  710.             break;
  711.  
  712.         case ( SQSTAT_PAUSED   ):
  713.             printf( "CD Paused\n" );
  714.             break;
  715.  
  716.         case ( SQSTAT_DONE     ):
  717.             printf( "Last Play finished normally\n" );
  718.             break;
  719.  
  720.         case ( SQSTAT_ERROR    ):
  721.             printf( "Last Play finished with error\n" );
  722.             break;
  723.         }
  724.  
  725.     // Position
  726.     if ( AddrInfo == ADRCTL_POSITION )
  727.         {
  728.         printf( "Current track %d, index %d\n",
  729.             ReqSubQ.Track,
  730.             ReqSubQ.Index );
  731.  
  732.         printf( "Minute:Second:Frame %d:%d:%d into CD, %d:%d:%d into track\n",
  733.             ReqSubQ.DiskPosition.MSF.Minute,
  734.             ReqSubQ.DiskPosition.MSF.Second,
  735.             ReqSubQ.DiskPosition.MSF.Frame,
  736.             ReqSubQ.TrackPosition.MSF.Minute,
  737.             ReqSubQ.TrackPosition.MSF.Second,
  738.             ReqSubQ.TrackPosition.MSF.Frame );
  739.         }
  740.     }
  741.  
  742.  
  743. /*************************
  744.  CDTV_PAUSE
  745.  *************************/
  746.  
  747.     {
  748.     IOReq->io_Command = CDTV_PAUSE;
  749.     IOReq->io_Offset  = 0;
  750.     IOReq->io_Length  = TRUE;
  751.     IOReq->io_Data    = NULL;
  752.     if ( Err = DoIO( (struct IORequest *) IOReq ) )
  753.         printf( "IO Error %ld\n", Err );
  754.     }
  755.  
  756.  
  757. /*************************
  758.  CDTV_STOPPLAY
  759.  *************************/
  760.  
  761.     {
  762.     // Remember to AbortIO the current play command first
  763.     IOReq->io_Command = CDTV_STOPPLAY;
  764.     IOReq->io_Offset  = 0;
  765.     IOReq->io_Length  = 0;
  766.     IOReq->io_Data    = NULL;
  767.     if ( Err = DoIO( (struct IORequest *) IOReq ) )
  768.         printf( "IO Error %ld\n", Err );
  769.     }
  770.  
  771.  
  772. /*************************
  773.  CDTV_POKESEGLSN
  774.  *************************/
  775.  
  776.     {
  777.     struct IOStdReq   PokeIOReq;
  778.     struct MinList    SegList;
  779.     struct CDAudioSeg SegNode;
  780.     CDPOS NewSector;
  781.  
  782.     // Use a copy of our IOReq
  783.     PokeIOReq = *IOReq;
  784.  
  785.     // Prepare list
  786.     NewList( (struct List *) &SegList );
  787.  
  788.     AddTail( (struct List *) &SegList, (struct Node *) &SegNode );
  789.     SegNode.Start.LSN = 16;
  790.     SegNode.Stop.LSN  = 300;
  791.  
  792.     IOReq->io_Command = CDTV_PLAYSEGSLSN;
  793.     IOReq->io_Offset  = 0;
  794.     IOReq->io_Length  = 0;
  795.     IOReq->io_Data    = (APTR) SegList.mlh_Head;
  796.     SendIO( (struct IORequest *) IOReq );
  797.  
  798.     // Actual "poke"
  799.     NewSector.LSN          = 480;
  800.  
  801.     PokeIOReq->io_Command = CDTV_POKESEGLSN;
  802.     PokeIOReq->io_Offset  = (ULONG) NewSector;
  803.     PokeIOReq->io_Length  = 0;
  804.     PokeIOReq->io_Data    = (APTR) SegList.mlh_Head;
  805.     if ( Err = DoIO( (struct IORequest *) PokeIOReq ) )
  806.         printf( "IO Error %ld\n", Err );
  807.  
  808.     // Cleanup:
  809.     WaitIO( (struct IORequest *) IOReq );
  810.     }
  811.  
  812.  
  813. /*************************
  814.  CDTV_POKESEGMSF
  815.  *************************/
  816.  
  817.  
  818.     {
  819.     struct IOStdReq   PokeIOReq;
  820.     struct MinList    SegList;
  821.     struct CDAudioSeg SegNode;
  822.     CDPOS NewMSF;
  823.  
  824.     // Use a copy of our IOReq
  825.     PokeIOReq = *IOReq;
  826.  
  827.     // Prepare list
  828.     NewList( (struct List *) &SegList );
  829.  
  830.     AddTail( (struct List *) &SegList, (struct Node *) &SegNode );
  831.     SegNode.Start.Raw = TOMSF( 5,  0,  0 );
  832.     SegNode.Stop.Raw  = TOMSF( 5, 10, 25 );
  833.  
  834.     IOReq->io_Command = CDTV_PLAYSEGSLSN;
  835.     IOReq->io_Offset  = 0;
  836.     IOReq->io_Length  = 0;
  837.     IOReq->io_Data    = (APTR) SegList.mlh_Head;
  838.     SendIO( (struct IORequest *) IOReq );
  839.  
  840.     // Actual "poke"
  841.     NewMSF.Raw          = TOMSF( 6, 10, 20 );
  842.  
  843.     PokeIOReq->io_Command = CDTV_POKESEGMSF;
  844.     PokeIOReq->io_Offset  = (ULONG) NewSector;
  845.     PokeIOReq->io_Length  = 0;
  846.     PokeIOReq->io_Data    = (APTR) SegList.mlh_Head;
  847.     if ( Err = DoIO( (struct IORequest *) PokeIOReq ) )
  848.         printf( "IO Error %ld\n", Err );
  849.  
  850.     // Cleanup:
  851.     WaitIO( (struct IORequest *) IOReq );
  852.     }
  853.  
  854.  
  855. /*************************
  856.  CDTV_MUTE
  857.  *************************/
  858.  
  859.     {
  860.     IOReq->io_Command = CDTV_MUTE;
  861.     IOReq->io_Offset  = 0;        // Volume 0-0x7FFF
  862.     IOReq->io_Length  = 1;        // 0=check, 1=next play stop, 2=now
  863.     IOReq->io_Data    = NULL;
  864.     if ( Err = DoIO( (struct IORequest *) IOReq ) )
  865.         printf( "IO Error %ld\n", Err );
  866.     }
  867.  
  868.  
  869. /*************************
  870.  CDTV_FADE
  871.  *************************/
  872.  
  873.     {
  874.     ULONG Seconds      = 2;
  875.  
  876.     IOReq->io_Command = CDTV_FADE;
  877.     IOReq->io_Offset  = 0x7FFF;    // Volume 0-0x7FFF
  878.     IOReq->io_Length  = ( Seconds * 75 );
  879.     IOReq->io_Data    = NULL;
  880.     if ( Err = DoIO( (struct IORequest *) IOReq ) )
  881.         printf( "IO Error %ld\n", Err );
  882.     }
  883.  
  884.  
  885. /*************************
  886.  CDTV_POKEPLAYLSN
  887.  *************************/
  888.  
  889.     {
  890.     struct IOStdReq PokeIOReq;
  891.     CDPOS StartSector;
  892.     CDPOS SecondSector;
  893.     CDPOS SectorsLength;
  894.  
  895.     // Use a copy of our IOReq
  896.     PokeIOReq = *IOReq;
  897.  
  898.     StartSector.LSN   = 16;
  899.     SectorsLength.LSN = 300;
  900.  
  901.     IOReq->io_Command = CDTV_PLAYLSN;
  902.     IOReq->io_Offset  = StartSector;
  903.     IOReq->io_Length  = SectorsLength;
  904.     IOReq->io_Data    = NULL;
  905.     SendIO( (struct IORequest *) IOReq );
  906.  
  907.     // Actual "poke"
  908.     SecondSector.LSN  = 480;
  909.  
  910.     PokeIOReq->io_Command = CDTV_POKEPLAYLSN;
  911.     PokeIOReq->io_Offset  = SecondSector;
  912.     PokeIOReq->io_Length  = SectorsLength;
  913.     PokeIOReq->io_Data    = NULL;
  914.     if ( Err = DoIO( (struct IORequest *) PokeIOReq ) )
  915.         printf( "IO Error %ld\n", Err );
  916.  
  917.     // Cleanup:
  918.     WaitIO( (struct IORequest *) IOReq );
  919.     }
  920.  
  921.  
  922. /*************************
  923.  CDTV_POKEPLAYMSF
  924.  *************************/
  925.  
  926.     {
  927.     struct IOStdReq PokeIOReq;
  928.     CDPOS StartMSF;
  929.     CDPOS SecondMSF;
  930.     CDPOS StopMSF;
  931.  
  932.     // Use a copy of our IOReq
  933.     PokeIOReq = *IOReq;
  934.  
  935.     StartMSF.Raw      = TOMSF( 5,  0,  0 );
  936.     SecondMSF.Raw      = TOMSF( 5, 40,  0 );
  937.  
  938.     IOReq->io_Command = CDTV_PLAYMSF;
  939.     IOReq->io_Offset  = (ULONG) StartMSF;
  940.     IOReq->io_Length  = (ULONG) StopMSF;
  941.     IOReq->io_Data    = NULL;
  942.     SendIO( (struct IORequest *) IOReq );
  943.  
  944.     // Actual "poke"
  945.     StopMSF.Raw      = TOMSF( 5, 10, 25 );
  946.  
  947.     PokeIOReq->io_Command = CDTV_POKEPLAYMSF;
  948.     PokeIOReq->io_Offset  = (ULONG) SecondMSF;
  949.     PokeIOReq->io_Length  = (ULONG) StopMSF;
  950.     PokeIOReq->io_Data    = NULL;
  951.     if ( Err = DoIO( (struct IORequest *) PokeIOReq ) )
  952.         printf( "IO Error %ld\n", Err );
  953.  
  954.     // Cleanup:
  955.     WaitIO( (struct IORequest *) IOReq );
  956.     }
  957.  
  958.  
  959. /*************************
  960.  CDTV_GENLOCK
  961.  *************************/
  962.  
  963.     {
  964.     IOReq->io_Command = CDTV_GENLOCK;
  965.     IOReq->io_Offset  = CDTV_GENLOCK_MIXED;
  966.     IOReq->io_Length  = 0;
  967.     IOReq->io_Data    = NULL;
  968.     if ( Err = DoIO( (struct IORequest *) IOReq ) )
  969.         printf( "IO Error %ld\n", Err );
  970.     }